package com.yungu.swift.order.processor;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.assets.driver.model.vo.DriverVo;
import com.yungu.swift.assets.driver.service.DriverService;
import com.yungu.swift.assets.passenger.model.dto.PassengerDto;
import com.yungu.swift.assets.passenger.model.vo.PassengerVo;
import com.yungu.swift.assets.passenger.service.PassengerService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.constants.FinanceConstant;
import com.yungu.swift.constants.OrderConstant;
import com.yungu.swift.order.model.vo.PayVo;
import com.yungu.swift.system.finance.model.dto.FinanceOrderDto;
import com.yungu.swift.system.finance.service.FinanceOrderService;
import com.yungu.swift.system.sys.model.dto.SysAccountDriverDto;
import com.yungu.swift.system.sys.model.dto.SysAccountPlatformDto;
import com.yungu.swift.system.sys.service.SysAccountDriverService;
import com.yungu.swift.system.sys.service.SysAccountPlatformService;
import com.yungu.swift.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;


/**
 * Created by cuixiuyin on 2018/5/8.
 * 司机代付处理器
 */
@Component
public class DriverChargeFareDetailProcessor implements DriverProcessor {
    private static final Logger logger = LoggerFactory.getLogger(DriverChargeFareDetailProcessor.class);
    @Reference
    private PassengerService passengerService;
    @Reference
    private DriverService driverService;
    @Reference
    private FinanceOrderService financeOrderService;
    @Reference
    private SysAccountDriverService sysAccountDriverService;
    @Reference
    private SysAccountPlatformService sysAccountPlatformService;

    @Override
    public void process(PayVo payVo) {
        //初始化乘客信息
        PassengerVo passengerVo = passengerService.selInfo(payVo.getPassengerVo().getUuid()).getData();
        payVo.setPassengerVo(passengerVo);
        //初始化司机信息
        DriverVo driverVo = driverService.selInfo(payVo.getDriverVo().getUuid()).getData();
        payVo.setDriverVo(driverVo);
        //更新乘客信息
        PassengerDto passengerParam = new PassengerDto();
        passengerParam.setUuid(payVo.getPassengerVo().getUuid());
        int passengerOrderCount = Optional.of(payVo.getPassengerVo().getOrderCount()).orElse(0) + 1;
        passengerParam.setOrderCount(passengerOrderCount);
        passengerVo.setOrderCount(passengerOrderCount);
        CompletableFuture.runAsync(() -> passengerService.edit(passengerParam)).whenComplete((t, throwable) ->
                logger.info("增加乘客订单数成功，orderUuid：{}", payVo.getOrderUuid()));

        //------------------------------------- 司机支付 ----------------------------------------

        //可提现余额
        BigDecimal canFrowardBalance = payVo.getAccountDriverBean().getCanFrowardBalance() == null ? BigDecimal.ZERO :
                new BigDecimal(payVo.getAccountDriverBean().getCanFrowardBalance().toString());
        //司机微信支付累积
        BigDecimal tenpayAccumulate = payVo.getAccountDriverBean().getTenpayAccumulate() == null ? BigDecimal.ZERO :
                new BigDecimal(payVo.getAccountDriverBean().getTenpayAccumulate().toString());
        //司机微信支付累积
        BigDecimal alipayAccumulate = payVo.getAccountDriverBean().getAlipayAccumulate() == null ? BigDecimal.ZERO :
                new BigDecimal(payVo.getAccountDriverBean().getAlipayAccumulate().toString());

        ResponseData<SysAccountPlatformDto> getPlatformAccount = sysAccountPlatformService.getByAppid(payVo.getAppid());
        if (!getPlatformAccount.isSuccess() || getPlatformAccount.getData() == null) {
            logger.error("获取不到平台账户信息，appid:{}", payVo.getAppid());
            return;
        }
        SysAccountPlatformDto accountPlatformDto = getPlatformAccount.getData();

        //1. 记录流水
        FinanceOrderDto financeOrderDto = new FinanceOrderDto();
        financeOrderDto.setUuid(StringUtils.buildUUID());
        financeOrderDto.setBusinessUuid(payVo.getOrderUuid());
        financeOrderDto.setOrderUuid(payVo.getOrderUuid());
        financeOrderDto.setAmount(payVo.getActualFare());
        financeOrderDto.setFinanceNumber(StringUtils.buildUUID());
        financeOrderDto.setFinanceInflow(accountPlatformDto.getUuid());
        financeOrderDto.setFinanceOutflow(payVo.getDriverVo().getUuid());
        financeOrderDto.setHappenTime(new Date());
        financeOrderDto.setCreateOn(new Date());

        //备注信息
        StringBuffer costDescription = new StringBuffer(String.format("orderUuid: %s", payVo.getOrderUuid()));
        //余额支付
        if (payVo.getPayType() == OrderConstant.PAY_TYPE_BALANCE) {
            costDescription.append("司机账户余额" + canFrowardBalance + "元,");
            //增加司机代付流水 再修改司机账户余额
            financeOrderDto.setCourse(FinanceConstant.DRIVER_BALANCE_PAY);
            financeOrderDto.setDescription("司机使用可提现余额支付车费" + payVo.getActualFare() + "元给平台");
            financeOrderDto.setCreateBy(payVo.getDriverVo().getUuid());
            financeOrderDto.setStartBalance(canFrowardBalance);
            // 减少司机可提现金额
            canFrowardBalance = canFrowardBalance.subtract(payVo.getActualFare());
            financeOrderDto.setFinalBalance(canFrowardBalance);
            costDescription.append("司机通过[余额]支付行程单，支付" + payVo.getActualFare().toString() + "元，现余额" + canFrowardBalance + "元");
        }
        //微信支付
        else if (payVo.getPayType() == OrderConstant.PAY_TYPE_TENPAY) {
            // 增加司机微信支付流水记录 增加司机账户微信支付累积金额
            financeOrderDto.setCourse(FinanceConstant.DRIVER_TEN_PAY);
            financeOrderDto.setDescription("司机使用微信支付" + payVo.getActualFare() + "元给平台");
            financeOrderDto.setCreateBy(payVo.getUserUuid());
            financeOrderDto.setStartBalance(tenpayAccumulate);
            //增加司机账户微信支付累积金额
            tenpayAccumulate = tenpayAccumulate.add(payVo.getActualFare());
            financeOrderDto.setFinalBalance(tenpayAccumulate);
            costDescription.append("司机微信支付流水记录：司机使用微信支付车费" + payVo.getActualFare() + "元给平台");
        }
        //支付宝支付
        else if (payVo.getPayType() == OrderConstant.PAY_TYPE_ALIPAY) {
            // 增加司机支付宝支付流水记录 增加司机账户支付宝支付累积金额
            financeOrderDto.setCourse(FinanceConstant.DRIVER_ALI_PAY);
            financeOrderDto.setDescription("司机使用支付宝支付" + payVo.getActualFare() + "元给平台");
            financeOrderDto.setCreateBy(payVo.getUserUuid());
            financeOrderDto.setStartBalance(alipayAccumulate);
            //增加司机账户支付宝支付累积金额
            alipayAccumulate = alipayAccumulate.add(payVo.getActualFare());
            financeOrderDto.setFinalBalance(alipayAccumulate);
            costDescription.append("司机支付宝支付流水记录：司机使用支付宝支付车费" + payVo.getActualFare() + "元");
        }

        CompletableFuture.runAsync(() -> financeOrderService.add(financeOrderDto)).whenComplete((t, throwable) ->
                logger.info(costDescription.toString())
        );

        // 2. 修改订单司机账户信息
        payVo.getAccountDriverBean().setCanFrowardBalance(canFrowardBalance);
        payVo.getAccountDriverBean().setTenpayAccumulate(tenpayAccumulate);
        payVo.getAccountDriverBean().setAlipayAccumulate(alipayAccumulate);

        // 3. 修改司机账户信息
        SysAccountDriverDto sysAccountDriverParam = new SysAccountDriverDto();
        sysAccountDriverParam.setUuid(payVo.getDriverVo().getUuid());
        sysAccountDriverParam.setCanFrowardBalance(canFrowardBalance);
        sysAccountDriverParam.setTenpayAccumulate(tenpayAccumulate);
        sysAccountDriverParam.setAlipayAccumulate(alipayAccumulate);
        sysAccountDriverParam.setUpdateOn(new Date());
        sysAccountDriverParam.setUpdateBy(payVo.getDriverVo().getUuid());
        CompletableFuture.runAsync(() -> sysAccountDriverService.edit(sysAccountDriverParam)).whenComplete((t, throwable) ->
                logger.info("订单:{}, 更新司机账户成功", payVo.getOrderUuid()));

        // 4. 如果是余额支付需要修改平台账户信息
        if (payVo.getPayType() == OrderConstant.PAY_TYPE_BALANCE) {
            accountPlatformDto.setCashBalance(accountPlatformDto.getCashBalance().add(payVo.getActualFare()).setScale(
                    1, BigDecimal.ROUND_HALF_UP));
            accountPlatformDto.setUpdateOn(new Date());
            CompletableFuture.runAsync(() -> sysAccountPlatformService.edit(accountPlatformDto)).whenComplete((t, throwable) ->
                    logger.info("订单:{}余额支付, 更新平台账户成功", payVo.getOrderUuid()));
        }
        logger.info(payVo.getDescription() + "--处理司机代付行程单流水逻辑完毕");
    }
}
